package cn.congine.wizarpos.mall.utils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import org.apache.commons.codec.binary.Hex;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Administrator
 */
public class WxSignUtil {
	private ArrayList<String> m_param_to_sign;

	public WxSignUtil() {
		m_param_to_sign = new ArrayList<String>();
	}

	public void AddData(String value) {
		m_param_to_sign.add(value);
	}

	public void AddData(Integer value) {
		m_param_to_sign.add(value.toString());
	}

	public static String urlEncode(String src) {
		try {
			return URLEncoder.encode(src, "UTF-8").replace("+", "%20");
		} catch (UnsupportedEncodingException e) {
			return src;
		}
	}

	public static boolean isEmpty(String str) {
		return ((str == null) || (str.length() == 0) || (str.trim().length() == 0));
	}

	public static String getMD5Radom() {
		Random random = new Random();
		String _rand = String.valueOf(random.nextInt(10000));
		MessageDigest md;
		try {
			md = MessageDigest.getInstance("MD5");
			byte[] array = md.digest(_rand.getBytes());
			return new String(Hex.encodeHex(array));
		} catch (NoSuchAlgorithmException e) {
			return null;
		}
	}

	public String GetSignature() {
		Collections.sort(m_param_to_sign);
		StringBuilder string_to_sign = new StringBuilder();
		for (String str : m_param_to_sign) {
			string_to_sign.append(str);
		}
		System.out.println("string_to_sign:" + string_to_sign);
		try {
			MessageDigest hasher = MessageDigest.getInstance("SHA-1");
			byte[] digest = hasher.digest(string_to_sign.toString().getBytes());
			return ByteToHexString(digest);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return "";
		}
	}

	public String ByteToHexString(byte[] data) {
		StringBuilder str = new StringBuilder();
		for (byte b : data) {
			String hv = Integer.toHexString(b & 0xFF);
			if (hv.length() < 2)
				str.append("0");
			str.append(hv);
		}
		return str.toString();
	}

	/**
	 * 卡券扩展字段签名
	 * 
	 * @param api_ticket
	 * @param card_id
	 * @param timestamp
	 * @param code
	 * @param openid
	 * @return
	 * @throws Exception
	 */
	public static String extSign(String api_ticket, String card_id,
			String timestamp, String code, String openid) throws Exception {
		WxSignUtil signer = new WxSignUtil();
		signer.AddData(api_ticket);
		signer.AddData(card_id);
		signer.AddData(timestamp);
		signer.AddData(code);
		signer.AddData(openid);
		return signer.GetSignature();
	}

	/**
	 * 卡券签名
	 * 
	 * @param api_ticket
	 * @param app_id
	 * @param location_id
	 * @param timestamp
	 * @param nonce_str
	 * @param card_id
	 * @param card_type
	 * @return
	 * @throws Exception
	 */
	public static String cardSign(String api_ticket, String app_id,
			String location_id, String timestamp, String nonce_str,
			String card_id, String card_type) throws Exception {
		WxSignUtil signer = new WxSignUtil();
		signer.AddData(api_ticket);
		signer.AddData(app_id);
		signer.AddData(location_id);
		signer.AddData(timestamp);
		signer.AddData(nonce_str);
		signer.AddData(card_id);
		signer.AddData(card_type);
		return signer.GetSignature();
	}

	/**
	 * 微信config接口签名
	 * 
	 * @param jsapi_ticket
	 * @param url
	 * @param time
	 * @return
	 */
	public static Map<String, String> commonSign(String jsapi_ticket,
			String url, long time) {
		Map<String, String> ret = new HashMap<String, String>();
		String nonce_str = createNoncestr();
		String timestamp = String.valueOf(time);
		String string1;
		String signature = "";

		// 注意这里参数名必须全部小写，且必须有序
		string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str
				+ "&timestamp=" + timestamp + "&url=" + url;
		System.out.println(string1);

		try {
			MessageDigest crypt = MessageDigest.getInstance("SHA-1");
			crypt.reset();
			crypt.update(string1.getBytes("UTF-8"));
			signature = byteToHex(crypt.digest());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		ret.put("url", url);
		ret.put("jsapi_ticket", jsapi_ticket);
		ret.put("noncestr", nonce_str);
		ret.put("timestamp", timestamp);
		ret.put("signature", signature);

		return ret;
	}

	/**
	 * 微信定位接口签名
	 * 
	 * @param accesstoken
	 * @param appId
	 * @param url
	 * @param timestamp
	 * @param nonce_str
	 * @return
	 */
	public static String signLocation(String accesstoken, String appId,
			String url, String timestamp, String nonce_str) {
		String string1;
		String addrSign = "";

		// 注意这里参数名必须全部小写，且必须有序
		string1 = "accesstoken=" + accesstoken + "&appId=" + appId
				+ "&noncestr=" + nonce_str + "&timestamp=" + timestamp
				+ "&url=" + url;
		System.out.println(string1);

		try {
			MessageDigest crypt = MessageDigest.getInstance("SHA-1");
			crypt.reset();
			crypt.update(string1.getBytes("UTF-8"));
			addrSign = byteToHex(crypt.digest());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		return addrSign;
	}

	private static String byteToHex(final byte[] hash) {
		Formatter formatter = new Formatter();
		for (byte b : hash) {
			formatter.format("%02x", b);
		}
		String result = formatter.toString();
		formatter.close();
		return result;
	}

	public static long createTimestamp() {
		return System.currentTimeMillis() / 1000;
	}

	public static String createNoncestr() {
		return UUID.randomUUID().toString();
	}

}
